/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cip.esymons.tesoreria.bc;

import java.util.List;
import javax.persistence.EntityManager;
import org.cip.esymons.general.be.Solicitante;
import org.cip.esymons.general.util.Utiles;
import org.cip.esymons.tesoreria.adapters.DeudaCuentaIngreso;
import org.cip.esymons.tesoreria.be.AutorizacionPagoParcial;
import org.cip.esymons.tesoreria.be.DetDocupago;
import org.cip.esymons.tesoreria.be.DetPagoAgrupado;
import org.cip.esymons.tesoreria.be.DocumentoPago;
import org.cip.esymons.tesoreria.be.EnumEstadoAutorizacion;
import org.cip.esymons.tesoreria.be.EnumEstadoMovimiento;
import org.cip.esymons.tesoreria.be.EnumTipoDeuda;
import org.cip.esymons.tesoreria.be.MovimientoCuenta;

/**
 *
 * @author Gilmar Montoya
 */
public class DocumentoPagoConPagoParcial extends DecoradorDocumentoPago {
    private Double igv=0.0;
    @Override
    public void generarDetalles(EntityManager em, Solicitante solicitante, DocumentoPago documentoPago, DeudaCuentaIngreso deudaCuentaIngreso, boolean realizarPago) {
        /*Ordenar por TipoAdministrado*/
        for (DetPagoAgrupado dxci : deudaCuentaIngreso.getListaDeudaxIngreso()) {
            dxci.setValor(dxci.getValorModificable());
            //codigo agregado x Ingrid
            if (documentoPago.getFkTdoCodigo().getTdoDesc().toLowerCase().equals("factura") || documentoPago.getFkTdoCodigo().getTdoDesc().toLowerCase().equals("boleta")) {
                if ((!dxci.getCuentaIngreso().getCinCodigo().equals("000")) && (dxci.getCuentaIngreso().getEsAfectoIgv() == true)) {
                    dxci.setValor(Utiles.redondearDouble(dxci.getValorModificable() / (1 + (igv/100)), 2));
                }
            }
            if (!dxci.getIsModificable()) {
                dxci.setDocCodigo(documentoPago);
                if (dxci.getCuentaIngreso().getCinCodigo().equals("000")) {
                    dxci.setCuentaIngreso(null);
                    dxci.getListaMovimientos().addAll(obtenerMovimientosDeCuota(em, dxci.getMes(), dxci.getAnio(), solicitante));
                }
                em.persist(dxci);
                for (MovimientoCuenta mc : dxci.getListaMovimientos()) {
                    DetDocupago detDocupago = new DetDocupago();
                    detDocupago.setDdpMontopago(mc.getMcuSaldo());
                    detDocupago.setPagoAgrupado(dxci);
                    detDocupago.setMcuCodigo(mc);
                    em.persist(detDocupago);
                    if (realizarPago) {
                        mc.setEstado(EnumEstadoMovimiento.Pagada);
                        mc.setMcuSaldo(0D);
                        em.merge(mc);
                    }
                }
            } else {
                if (dxci.getListaMovimientos().size() > 0) {
                    dxci.setDocCodigo(documentoPago);
                    if (dxci.getCuentaIngreso().getCinCodigo().equals("000")) {
                        dxci.setCuentaIngreso(null);
                        dxci.getListaMovimientos().addAll(obtenerMovimientosDeCuota(em, dxci.getMes(), dxci.getAnio(), solicitante));
                    }
                    em.persist(dxci);
                    Double monto = Utiles.redondearDouble(dxci.getValorModificable() / dxci.getListaMovimientos().size(), 2);
                    for (MovimientoCuenta mc : dxci.getListaMovimientos()) {
                        DetDocupago detDocupago = new DetDocupago();
                        detDocupago.setDdpMontopago(monto);
                        detDocupago.setPagoAgrupado(dxci);
                        detDocupago.setMcuCodigo(mc);
                        em.persist(detDocupago);
                        if (realizarPago) {
                            Double saldo = 0.0;
                            if (mc.isPagoParcial()) {
                                AutorizacionPagoParcial aut = obtenerAutorizacion(em, mc.getMcuCodigo());
                                if (aut != null) {
                                    aut.setPapEstado(EnumEstadoAutorizacion.Realizado);
                                    em.merge(aut);                                    
                                    saldo = aut.getPapMonto() - aut.getPapSaldoModificado();
                                    mc.setPagoParcial(false);
                                }
                            } else {
                                saldo = Utiles.redondearDouble(mc.getMcuSaldo() - monto, 2);
                            }
                            if (saldo > 0) {
                                mc.setEstado(EnumEstadoMovimiento.Impaga);
                            } else {
                                saldo = 0.0;
                                mc.setEstado(EnumEstadoMovimiento.Pagada);
                            }
                            mc.setMcuSaldo(saldo);
                            em.merge(mc);
                        } else {
                            mc.setEstado(EnumEstadoMovimiento.Por_Cancelar);
                            em.merge(mc);
                        }
                    }
                }
            }
        }
    }

    private AutorizacionPagoParcial obtenerAutorizacion(EntityManager em, Long codigo) {
        try {
            List<AutorizacionPagoParcial> lista = em.createQuery("Select o From AutorizacionPagoParcial o Where o.papEstado=?1 and o.mcuCodigo.mcuCodigo=?2").setParameter(1, EnumEstadoAutorizacion.Activo).setParameter(2, codigo).getResultList();
            if (lista.size() > 0) {
                return lista.get(0);
            } else {
                return null;
            }
        } catch (Exception e) {
            return null;
        }
    }

    private List<MovimientoCuenta> obtenerMovimientosDeCuota(EntityManager em, int mes, int anio, Solicitante solicitante) {
        try {
            return em.createQuery("select o.movimientoFraccionamiento.movimientoCuenta from MovimientoCuota o Where o.movimientoCuenta.mcuMes=?1 and o.movimientoCuenta.mcuAnio =?2 and o.movimientoCuenta.tipoDeuda=?3 and o.movimientoCuenta.fkSolCodigo=?4").setParameter(1, mes).setParameter(2, anio).setParameter(3, EnumTipoDeuda.FRACCIONAMIENTO).setParameter(4, solicitante).getResultList();
        } catch (Exception ex) {
            return null;
        }
    }

    @Override
    public Double calcularPago(MovimientoCuenta movimientoCuenta) {
        return getDocumentoPagoInterfaz().calcularPago(movimientoCuenta);
    }

    /**
     * @return the igv
     */
    public Double getIgv() {
        return igv;
    }

    /**
     * @param igv the igv to set
     */
    public void setIgv(Double igv) {
        this.igv = igv;
    }
}
